#!/usr/bin/env python
"""
:mod:`pynchon.bio.data.score`
=============================

Provides biological score matrices.
"""
import os
SCORE_MATRIX_PATH = os.path.join(os.path.dirname(__file__), 'score')

def parse_score_matrix(fh):
    """
    Parses a score matrix, which in the format of the matrices available at:
    ftp://ftp.ncbi.nih.gov/blast/matrices/. Code from adapted from:
    http://bitbucket.org/brentp/biostuff/src/tip/nwalign/pairwise.py
    Author:  brentp <bpederse at gmail com>  
    
    Arguments:
    
        - fh (``file``) An open for reading file handle.
        
    Returns a nested dictionary representation of the matrix.
    """
    m = {}
    headers = None
    while headers is None:
        line = fh.readline().strip()
        if line[0] == '#': continue
        headers = [x for x in line.split(' ') if x]
        for h in headers: m[h] = {}
    line = fh.readline()
    while line:
        h1 = line[0]
        line = [int(x) for x in line[1:-1].split(' ') if x]
        values = zip(headers, line)
        m[h1] = dict(values)
        line = fh.readline()
    return m

def parse_blosum_out(fh):
    """
    Parser a blosumXX.out file. Returns a dictionary.
    
    Arguments:
    
        - fh (``file``) An open for reading file handle.
    """
    result = {}
    if not fh.readline().startswith('BLOSUM'):
        raise ValueError('Not a valid blosumXX.out file.')
    line = fh.readline()
    while line:
        if line.startswith('Re-clustering'):
            id_ = line.split()[-1]
        if line.startswith('AA Probabilities'):
            aa = fh.readline().split()
            fi = [float(f) for f in fh.readline().split()]
            result['fi'] = dict(zip(aa, fi))
        line = fh.readline()
    return (id_, result)


blosum = {}
for fn in os.listdir(SCORE_MATRIX_PATH):
    ext = os.path.splitext(fn)[-1]
    fh = open(os.path.join(SCORE_MATRIX_PATH, fn), 'rb')
    if ext == '.out':
        id_, data = parse_blosum_out(fh)
        blosum[int(id_)] = data
    elif not ext:
        # score matric
        sm = parse_score_matrix(fh)
        globals()[fn] = sm
    else:
        fh.close()
        continue

    
    

    



